package com.learncloud.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.learncloud.common.core.Constant;
import com.learncloud.common.core.exception.ServiceException;
import com.learncloud.entity.vo.VideoCategoryVo;
import com.learncloud.entity.VideoCategory;
import com.learncloud.entity.VideoCategoryLabel;
import com.learncloud.entity.dto.VideoCategoryDto;
import com.learncloud.mapper.VideoCategoryMapper;
import com.learncloud.service.IVideoCategoryLabelService;
import com.learncloud.service.IVideoCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 视频类别表 服务实现类
 * </p>
 *
 * @author yj
 */
@Service
public class VideoCategoryServiceImpl extends ServiceImpl<VideoCategoryMapper, VideoCategory> implements IVideoCategoryService {

    @Autowired
    private VideoCategoryMapper videoCategoryMapper;

    @Autowired
    private IVideoCategoryLabelService iVideoCategoryLabelService;

    @Override
    public List<VideoCategoryVo> getCategoryVoList(VideoCategory videoCategory) {
        List<VideoCategoryVo> parents = new ArrayList<>();
        List<VideoCategory> list = this.list(new QueryWrapper<>(videoCategory).orderByAsc("sort"));
        for (VideoCategory item : list){
            if (item.getParentId().equals(0)){
                VideoCategoryVo parent = new VideoCategoryVo(item);
                getChild(parent,list);
                parents.add(parent);
            }
        }
        return parents;
    }

    @Override
    public Page getPaginationList(Page page, VideoCategory videoCategory) {
        // 分页查询父级菜单
        videoCategory.setParentId(0);
        page.setOrders(Arrays.asList(new OrderItem().setColumn("sort").setAsc(true)));
        page = this.page(page, new QueryWrapper<>(videoCategory));
        List<VideoCategory> records = page.getRecords();
        List<VideoCategoryVo> parents = new ArrayList<>();
        // 通过父级id批量递归查询所有子级
        if (records.size() > 0) {
            List<Integer> list = new ArrayList<>();
            for (VideoCategory item : records){
                list.add(item.getId());
            }
            List<VideoCategory> recursionByParentIds = videoCategoryMapper.findByParentIds(list);
            for (VideoCategory menu : records){
                VideoCategoryVo parent = new VideoCategoryVo(menu);
                getChild(parent,recursionByParentIds);
                parents.add(parent);
            }
            page.setRecords(parents);
        }
        return page;
    }

    @Override
    @Transactional
    public boolean add(VideoCategoryDto videoCategory) {
        boolean save = this.save(videoCategory);
        boolean b = addCategoryLabel(videoCategory);
        return save && b;
    }

    @Override
    @Transactional
    public boolean updateCategory(VideoCategoryDto videoCategory) {
        if (Constant.Status.DISABLE.value.equals(videoCategory.getStatus())){
            List<VideoCategory> list = this.list(new QueryWrapper<>(new VideoCategory().setParentId(videoCategory.getId()).setStatus(Constant.Status.ENABLE.value)));
            if (list.size() > 0){
                throw new ServiceException("禁用失败,请先禁用其子类别");
            }
        }
        boolean update = this.updateById(videoCategory);
        boolean b = addCategoryLabel(videoCategory);
        boolean b1 = delCategoryLabel(videoCategory);
        return update && b && b1;
    }

    @Override
    @Transactional
    public boolean del(Integer id) {
        List<VideoCategory> list = this.list(new QueryWrapper<>(new VideoCategory().setParentId(id).setStatus(Constant.Status.ENABLE.value)));
        if (list.size() > 0){
            throw new ServiceException("删除失败,请先删除其子类别");
        }
        boolean remove = this.removeById(id);
        boolean remove1 = iVideoCategoryLabelService.remove(new QueryWrapper<>(new VideoCategoryLabel().setCategoryId(id)));
        return remove && remove1;
    }

    @Override
    public VideoCategoryVo getDetails(Integer id) {
        VideoCategory byId = this.getById(id);
        VideoCategoryVo videoCategoryVo = new VideoCategoryVo(byId);
        List<VideoCategoryLabel> list = iVideoCategoryLabelService.list(new QueryWrapper<>(new VideoCategoryLabel().setCategoryId(id)));
        List labelIds = new ArrayList();
        for (VideoCategoryLabel categoryLabel : list){
            labelIds.add(categoryLabel.getLabelId());
        }
        videoCategoryVo.setLabelIds(labelIds);
        return videoCategoryVo;
    }


    private void getChild(VideoCategoryVo videoCategoryVo, List<VideoCategory> list){
        for (VideoCategory item : list){
            if (videoCategoryVo.getId().equals(item.getParentId())){
                if (videoCategoryVo.getChildren() == null){
                    videoCategoryVo.setChildren(new ArrayList<>());
                }
                List<VideoCategory> children = videoCategoryVo.getChildren();
                children.add(item);
            }
        }
    }

    private boolean addCategoryLabel(VideoCategoryDto videoCategoryDto){
        List<Integer> addLabelIds = videoCategoryDto.getAddLabelIds();
        boolean add = true;
        if (addLabelIds != null && addLabelIds.size() > 0 ) {
            List<VideoCategoryLabel> videoCategoryLabels = new ArrayList<>();
            VideoCategoryLabel videoCategoryLabel;
            for (Integer labelId : addLabelIds) {
                videoCategoryLabel = new VideoCategoryLabel();
                videoCategoryLabel.setLabelId(labelId).setCategoryId(videoCategoryDto.getId());
                videoCategoryLabels.add(videoCategoryLabel);
            }
            add = iVideoCategoryLabelService.saveBatch(videoCategoryLabels);
        }
        return add;
    }

    private boolean delCategoryLabel(VideoCategoryDto videoCategoryDto){
        List<Integer> delLabelIds = videoCategoryDto.getDelLabelIds();
        boolean del = true;
        if (delLabelIds != null && delLabelIds.size() > 0 ) {
            List<VideoCategoryLabel> list = iVideoCategoryLabelService.list(new QueryWrapper<>(new VideoCategoryLabel().setCategoryId(videoCategoryDto.getId())));
            List<Integer> delIds = new ArrayList<>();
            for (VideoCategoryLabel videoCategoryLabel : list) {
                if (delLabelIds.contains(videoCategoryLabel.getLabelId())){
                    delIds.add(videoCategoryLabel.getId());
                }
            }
            del = iVideoCategoryLabelService.removeByIds(delIds);
        }
        return del;
    }
}
